\section{Overview}

SOS implements a persistent storage for objects whose structure and
behavior is defined in an object-oriented manner, i.e. in terms of
classes, methods and inheritance.

In contrast to several recent developments in the area of persistent
object-oriented systems, SOS was not implemented as an enhancement to
some existing programming language.
%SOS is rather based on a data model that is restricted to the
%capabilities that several other programming languages
%have in common.
The SOS data model is in opposite to these approaches
designed to be independent from any concrete host language.
The embedding into a host language is done by generating appropriate
interfaces and code for this language from given SOS schemas.
An embedding into C++ has been implemented, one into Common Lisp is
planned.

\subsection{The Data Model}
The SOS data model provides mechanisms for defining 
types. These are defined in modules that are called {\it schemas}.
The notation for these type definitions within a schema is described
in Section~\ref{sec:The SOS Schema Language}.
%SOS distinguishes between several types, that are sketched in
%in the following.

{\it Enumeration types} are used to specify finite sets
of constants by listing the elements.
{\it External types} are used to manage the link to types of some
programming language.
Enumeration types and external types are called {\it scalar types};
they are the primitives from which classes and unions may be
constructed as will be described subsequently.
The set of objects whose type is a scalar type are (conceptually)
created together with the type definition; no objects of a scalar
type can be explicitly created.

The central notion in SOS is the notion of a {\it class}. 
Each class is declared by the structural and behavioral properties
common to its instances.
The structural properties are declared by {\em components}
(slots, or attributes, as they are called in other languages); 
the behavioral properties are declared by {\em methods} (operations, functions).
Class types provide information hiding capabilities by dividing the
methods into private, protected and public ones.
Public methods define the interface to the instances of the class,
whereas private and protected methods may be invoked only by the
implementation of the methods of the class itself, or its
derived classes, respectively.
Besides its state which is made up from its components every instance
has a unique system generated identifier that is representing its
identity. It can be used as a reference to this instance.

The components of an object may not only be
objects of scalar types (i.e. values) but also objects or
{\it references} to objects of the same or a different class.
Those components may be defined by value or by reference.
The difference between the two notions lies on the operational
part of the data model which is made up of the methods declared for
each class, respectively.
Components of an object which are defined by value, so-called
{\it value components}, are considered to be a dependent part of
the object that cannot further exist after the destruction of the
object. An object can only be a value component of one other object.
If such a connection between two objects is established once, it can
not be loosened any more. Consequently, it is not possible 
to perform an explicit destroy operation on a value component.
Objects, which are instances of classes, are explicitly created.
It is intended that value components are created together with the
creation and destroyed together with the destruction of their master
object.

%Each object gets a unique identifier with its creation.
%At an intuitive level, these identifiers can be seen as
%``typed pointers''.
%Identifiers are an essential part of object-oriented-data models
%and useful for describing structure sharing, updates and cyclicity.
%Two objects are called {\it identical} if they have the same
%identifiers.
Two objects are {\em identical} when they have the same identity;
two objects are {\it equal} if all of their non-value components are
identical, and their value components are equal.
That means, that the equality check is recursively applied to each of
the value components.

{\it Class inheritance} is a mechanism for factoring out common
properties of classes in parent classes. New classes
that inherit properties from existing classes are called 
{\em derived classes}.
The SOS data model supports multiple inheritance, which means
inheritance of a subclass from several parents; name clashes are
explicitly precluded. The "inherits from" relationship defines 
a partial order on a set of classes. 
All classes have a common parent class called {\tt sos\_Object}.
As a consequence, the type hierarchy may be visualized by a directed
acyclic graph with a single root node.

Another way of generalization is the definition of
{\it generic classes} which are parameterized with
{\it type parameters}.
The instantiation of a generic class generates the declaration of
a specific class by substituting actual types for the formal type
parameters in the according methods.
Arbitrary new type constructors, for instance \verb|Set<T>|
or \verb|List<T>|, may be defined as generic classes.
The result of an instantiation may then be a type like
\verb|Set<List <int>>|.

{\it Union types} may also be used to generalize types  in a way,
such that an instance of one of the united types may appear where
the union type is required.
It is not possible to create instances of a union type and no
methods are provided for them.
Union types are just a means to declare generalized types after the
more special classes.
In contrast to that, when using the type hierarchy  to describe
generalization, superclasses must be introduced before the more
specialized classes.

\subsection{System Aspects}
The data model which is sketched in the previous section
is realized by the SOS system. One part of the system, the SOS schema
compiler, is concerned with the compilation of SOS schemas.
During the compilation process the type information is made persistent.
This is done by creating an SOS object for each schema and 
each type definition within a schema.
The objects which are created later on by an application program
are associated with an object representing the type.
Those ``type objects'' are stored in the so-called {\it meta database},
their types are defined in the so-called {\it meta schema}. 
This allows to interpret an object dynamically
by inspecting the associated type object.
Components are accessed by using specific
get- and set-operations of the host programming language which are
generated automatically by the interface generator of the compiler.
For the components, SOS determines
a fixed and language independent storage layout.
The implementation of the methods specified within a class type definition
is done in some programming language
(which may be a compiled or an interpreted language).
Depending on the degree to which the language performs
type-checking, the interface generator of the schema compiler
generates appropriate interfaces and/or code for this language.

SOS comes with several predefined types like e.g. {\tt sos\_Object},
{\tt List} or {\tt Set}.
Section~\ref{sec:The SOS Environment} 
contains a description of these types.
One of the predefined types, the type {\tt sos\_Container},
should be noticed carefully, because it serves as an interface
to the persistent storage manager.
Each object of SOS belongs to exactly one container, which is
determined when an object is created.
The containers provide a simple mechanism for synchronization,
recovery and clustering of objects.
A detailed definition of all predefined types can be found in the
manual pages in Appendix~\ref{sec:Manual Pages}.

For each programming language for which an embedding of SOS is
provided, the specific concepts of SOS are mapped onto the concepts
of the host language.
For the current release of SOS, this is done for C++.
The C++ interface is described in Section~\ref{sec:Interface to C++}.
% ------------------------------------------------------------------

